package com.xthh._function;



import android.util.Log;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by lrs on 2018/2/27.
 */
public class HH_DownloadFTPUtil {
    public static HH_DownloadFTPUtil downloadFTPUtil;
    /**
     * 下载客户端
     */
    private FTPClient ftpClient;

    private String ftpIP;
    private int ftpPort;
    private String ftpUserName;//
    private String ftpPwd; //anonymous

    public HH_DownloadFTPUtil(String ip, int port, String userName, String pwd) {
        ftpIP = ip;
        ftpPort = port;
        ftpUserName = userName;
        if (ftpUserName.length() == 0)
            ftpUserName = "anonymous";
        ftpPwd = pwd;;
        if (ftpPwd.length() == 0)
            ftpPwd = "anonymous";
    }

    /**
     * 下载状态
     */
    public enum DownloadStatus {
        //远程文件不存在
        Remote_File_Noexist,
        //本地文件大于远程文件
        Local_Bigger_Remote,
        //断点下载文件成功
        Download_From_Break_Success,
        //断点下载文件失败
        Download_From_Break_Failed,
        //下载停止
        Download_From_Break_Stop,
        //下载中
        Download_From_Break_Ing
    }

    /**
     * 下载状态  0空白状态 1 下载中 暂停 2
     */
    private static int DownloadState;
    /**
     * 写出对象
     */
    private FileOutputStream out;
    /**
     * 写入对象
     */
    private InputStream in;
    /**
     *传递规格
     */
    private byte[] bytes = new byte[1024];

    /**
     * 线程管理（线程池）
     */
    private static ExecutorService singleThreadPool;

    /**
     * @return 获取唯一实例
     */
    public static HH_DownloadFTPUtil getInstance(String ip, int port, String userName, String pwd) {
        if (downloadFTPUtil == null) {
            downloadFTPUtil = new HH_DownloadFTPUtil(ip, port, userName, pwd);
        }
        if (singleThreadPool == null) {
            singleThreadPool = Executors.newSingleThreadExecutor();
        }
        return downloadFTPUtil;
    }

    /**
     * 断开FTP连接
     */
    public void disconnect() throws IOException {
        if (ftpClient != null && ftpClient.isConnected()) {
            ftpClient.disconnect();
        }
    }

    /**
     * 下载暂停
     */
    public void dowpause() {
        DownloadState = 2;
    }


    /**
     * 从FTP服务器上下载文件
     *
     * @param remote 远程文件路径
     * @param local  本地文件路径
     * @return 上传的状态
     * @throws IOException
     */

    public void downloadFile(final String remote, final String local, final OnDownloadListener listener) {
        //是否可以进行下载  当前是否无占用
        if (DownloadState == 1) {
            return;
        }
        singleThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    ftpClient = new FTPClient();
                    //连接服务器
                    ftpClient.connect(ftpIP, ftpPort);
                    ftpClient.setControlEncoding("GBK");
                    if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                        if (!ftpClient.login(ftpUserName, ftpPwd)) {
                            //关闭连接
                            disconnect();
                            DownloadState = 0;
                            listener.onFtpDownloadFailed(new NullPointerException());
                            return;
                        }
                    }
                    //设置传输超时时间为60秒
                    ftpClient.setDataTimeout(60000);
                    //连接超时为60秒
                    ftpClient.setConnectTimeout(60000);
                    //设置被动模式
                    ftpClient.enterLocalPassiveMode();
                    //设置以二进制方式传输
                    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                    //检查远程文件是否存在
                     FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"), "iso-8859-1"));
                    //FTPFile[] files = ftpClient.listFiles();
                    if (files.length != 1) {
                        System.out.println("远程文件不存在");
                        DownloadState = 0;
                        listener.onFtpDownloadFailed(new NullPointerException());
                        return;
                    }
                    long lRemoteSize = files[0].getSize();
                    File file = new File(local);
                    //本地文件大小
                    long localSize = 0L;
                    //检验本地文件
                    if (file.exists()) {
                        //本地已下载部分文件  需要断点续传
                        localSize = file.length();
                        //进行断点续传，并记录状态
                        out = new FileOutputStream(file, true);
                        //提交 已下载字节
                        ftpClient.setRestartOffset(localSize);
                    } else {
                        //本地未下载文件
                        out = new FileOutputStream(file);
                    }
                    //判断本地文件大小是否大于远程文件大
                    if (localSize >= lRemoteSize) {
                        Log.e("FTP", "本地已存在文件，下载中止");
                        DownloadState = 0;
                        return;
                    }
                    in = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"), "iso-8859-1"));
                    long step = lRemoteSize / 100;
                    long process = localSize / step;
                    int c;
                    while ((c = in.read(bytes)) != -1) {
                        out.write(bytes, 0, c);
                        localSize += c;
                        long nowProcess = localSize / step;
                        if (nowProcess > process) {
                            process = nowProcess;
                            //下载回传进度
                            DownloadState = 1;
                            listener.onFtpDownloading(lRemoteSize, localSize, Integer.parseInt(process + ""));
                            if (process >= 100) {
                                //下载完成
                                DownloadState = 0;
                                listener.onFtpDownloadSuccess("");
                            }
                        }
                        //终止下载
                        if (DownloadState == 2) {
                            DownloadState = 0;
                            //下载停止 （暂停）
                            listener.onFtpStop();
                            break;
                        }
                    }
                    if (in != null) {
                        in.close();
                    }
                    if (out != null) {
                        out.close();
                    }
                    disconnect();
                } catch (FTPConnectionClosedException e) {
                    Log.e("FTP", e.getLocalizedMessage());
                    Log.e("FTP", "连接数量已满");
                    try {
                        disconnect();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    listener.onFtpStop();
                } catch (Exception e) {
                    //出现异常下载失败
                    Log.e("FTP", e.getLocalizedMessage());
                    try {
                        if (in != null) {
                            in.close();
                        }
                        if (out != null) {
                            out.close();
                        }
                        disconnect();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    listener.onFtpDownloadFailed(e);
                }
            }
        });

    }

    // 获取文件字符串
    public String getFileBuffer(final String remote, final OnDownloadListener listener) {
        //是否可以进行下载  当前是否无占用
        if (DownloadState == 1) {
            return "";
        }
        singleThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    ftpClient = new FTPClient();
                    //连接服务器
                    ftpClient.connect(ftpIP, ftpPort);
                    ftpClient.setControlEncoding("GBK");
                    if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                        if (!ftpClient.login(ftpUserName, ftpPwd)) {
                            //关闭连接
                            disconnect();
                            DownloadState = 0;
                            listener.onFtpDownloadFailed(new NullPointerException());
                            return;
                        }
                    }
                    //设置传输超时时间为60秒
                    ftpClient.setDataTimeout(60000);
                    //连接超时为60秒
                    ftpClient.setConnectTimeout(60000);
                    //设置被动模式
                    ftpClient.enterLocalPassiveMode();
                    //设置以二进制方式传输
                    ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                    //检查远程文件是否存在
                    FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"), "iso-8859-1"));
                    //FTPFile[] files = ftpClient.listFiles();
                    if (files.length != 1) {
                        System.out.println("远程文件不存在");
                        DownloadState = 0;
                        listener.onFtpDownloadFailed(new NullPointerException());
                        return;
                    }
                    long lRemoteSize = files[0].getSize();


                    in = ftpClient.retrieveFileStream(new String(remote.getBytes("GBK"), "iso-8859-1"));
                    String downBuffer = "";
                    int c;
                    while ((c = in.read(bytes)) != -1) {

                        String temp = new String(bytes);
                        downBuffer += temp;
                    }

                    DownloadState = 0;
                    listener.onFtpDownloadSuccess(downBuffer);

                    if (in != null) {
                        in.close();
                    }
                    if (out != null) {
                        out.close();
                    }
                    disconnect();
                } catch (FTPConnectionClosedException e) {
                    Log.e("FTP", e.getLocalizedMessage());
                    Log.e("FTP", "连接数量已满");
                    try {
                        disconnect();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    listener.onFtpStop();
                } catch (Exception e) {
                    //出现异常下载失败
                    Log.e("FTP", e.getLocalizedMessage());
                    try {
                        if (in != null) {
                            in.close();
                        }
                        if (out != null) {
                            out.close();
                        }
                        disconnect();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    listener.onFtpDownloadFailed(e);
                }
            }
        });

        return "";
    }

    public interface OnDownloadListener {
        /**
         * 下载成功
         */
        void onFtpDownloadSuccess(String buffer);

        /**
         * 下载进度
         *
         * @param total    总大小
         * @param current  当前大小
         * @param progress 下载进度
         */
        void onFtpDownloading(long total, long current, int progress);

        /**
         * 下载失败
         */
        void onFtpDownloadFailed(Exception e);

        /**
         * 下载停止
         */
        void onFtpStop();
    }
}
